<template>
  <div class="carousel" @mouseenter="mouseEnter" @mouseleave="mouseLeave">
    <div class="inner">
      <dot-item
        :itemLen="itemLen"
        :currentIndex="currentIndex"
        :hasDot="hasDot"
        :dotBgColor="dotBgColor"
        @dotClick="dotClick"
      ></dot-item>
      <director-button dir="next" @dirClick="dirClick"></director-button>
      <director-button dir="prev" @dirClick="dirClick"></director-button>
      <slot></slot>
    </div>
  </div>
</template>

<script>
//onBeforeUnmount -> 组件卸载之前需要清除计时器
import {
  reactive,
  toRefs,
  getCurrentInstance,
  onMounted,
  onBeforeUnmount,
} from "vue";

import DotItem from "./Dot.vue";
import DirectorButton from "./Director.vue";

export default {
  name: "Carousel",
  components: {
    DotItem,
    DirectorButton,
  },
  props: {
    autoplay: {
      type: Boolean,
      default: true,
    },
    duration: {
      type: Number,
      default: 3000,
    },
    initial: {
      type: Number,
      default: 0,
    },
    hasDot: {
      type: Boolean,
      default: true,
    },
    hasDirector: {
      type: Boolean,
      default: true,
    },
    dotBgColor: String,
    autoplayDir: String,
  },
  setup(props) {
    let t = null;

    const instance = getCurrentInstance();
    const state = reactive({
      //拿到当前图片的初始值
      currentIndex: props.initial,
      //拿到v-for遍历每一项item的长度
      itemLen: 0,
    });

    //业务逻辑：

    //指示器的函数
    const dotClick = (index) => {
      //实现轮播图小圆点联动
      state.currentIndex = index;
    };

    //鼠标移入移出事件处理函数
    const mouseEnter = () => {
      _clearInterval();
    };
    const mouseLeave = () => {
      autoPlay();
    };

    //实现点击prev/next按钮显示前一张或后一张图片
    const dirClick = (dir) => {
      setIndex(dir);
    };

    //自动轮播图实现
    const autoPlay = () => {
      if (props.autoplay) {
        t = setInterval(() => {
          //问题1：到达第5张图/第1张图需要做什么操作？
          //问题2：方向

          //这里是设置自动轮播时是向前还是向后
          setIndex(props.autoplayDir);
        }, props.duration);
      }
    };

    //更改currentIndex下标来显示指定图片
    const setIndex = (dir) => {
      switch (dir) {
        case "next":
          //下一张图时下标currentIndex + 1
          state.currentIndex += 1;
          //itemLen -> v-for遍历子组件每一项item的长度
          //说明到达了最后一张图
          if (state.currentIndex === state.itemLen) {
            //回归第一张
            state.currentIndex = 0;
          }
          break;
        case "prev":
          state.currentIndex -= 1;
          //说明到达了第一张
          //注意：这里不能写state.currentIndex === 0
          //因为：0需要显示出来，可以写为-1
          if (state.currentIndex === -1) {
            //回归最后一张
            state.currentIndex = state.itemLen - 1;
          }
          break;
        default:
          break;
      }
    };

    onMounted(() => {
      //组件挂载完成渲染完毕时
      /**
       * 通过组件实例slots.default()拿到一个数组
       * children里的每一项相当于v-for遍历的每一项item
       * 且可以拿到遍历的长度
       * console.log(instance.slots.default());
       * [
       *   {
       *     ...,
       *     children: [
       *       {...},
       *       {...},
       *       {...},
       *       length: 3
       *     ]
       *   }
       * ]
       */

      //挂在完毕时将默认值0改为遍历子组件后的item的长度
      state.itemLen = instance.slots.default()[0].children.length;

      // console.log(state.itemLen);
      //3

      autoPlay();
    });

    onBeforeUnmount(() => {
      _clearInterval();
    });

    function _clearInterval() {
      clearInterval(t);
      t = null;
    }

    return {
      ...toRefs(state),
      dotClick,
      mouseEnter,
      mouseLeave,
      dirClick,
    };
  },
};
</script>

<style lang="scss" scoped>
.carousel {
  width: 100%;
  height: 100%;

  .inner {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
  }
}
</style>